/*
 * AssertionConsumerService.java
 * 
 * Version information
 * 
 * Apr 10, 2006
 * 
 * Copyright (c) AmSoft Systems, 2006
 */
package net.amsoft.iservice.ilink.webapp.struts.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.amsoft.iservice.ilink.webapp.dataObject.LoginData;
import net.amsoft.iservice.ilink.util.ILinkConstants;
import net.amsoft.iservice.isso.client.ISSOClient;
import net.amsoft.iservice.isso.client.SAMLDataObject;
import net.amsoft.iservice.util.ResolverClient;

import org.apache.log4j.Logger;
import org.apache.soap.Envelope;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.MessageResources;

/**
 * The SAML standard defines a framework for exchanging security information
 * between software entities on the Web. SAML security is based on the
 * interaction of asserting and relying parties. Class AssertionConsumer ensures
 * the secure communication between the entities while saving the information.
 * 
 * @author mohit
 * 
 */

public class AssertionConsumerService extends BaseAction {
	public static final Logger oLogger = Logger
			.getLogger(AssertionConsumerService.class);

	public ActionForward process(ActionMapping oMapping,
			ActionForm oActionForm, HttpServletRequest oRequest,
			HttpServletResponse oResponse) throws Exception {
		oLogger.info("process() : entry");
		ActionMessages oMsgs = new ActionErrors();
		LoginData oLoginData = (LoginData) oRequest.getSession(false)
				.getAttribute(ILinkConstants.SESSION_LOGIN_OBJ);

		String sSAMLArtifactDoc = oRequest
				.getParameter(ISSOClient.PARAM_SAML_ART);

		String sRelayState = oRequest
				.getParameter(ISSOClient.PARAM_RELAY_STATE);

		SAMLDataObject oReceivedSAMLData = ISSOClient
				.getValuesFromSAMLArtifact(sSAMLArtifactDoc);

		if (!sRelayState.equals(oLoginData.getRelayState())
				|| !oLoginData.getProviderIDHash().equals(
						oReceivedSAMLData.getProviderIDHash())) {
			oMsgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
					ILinkConstants.ERR_INVALID, "request"));
			saveErrors(oRequest.getSession(false), oMsgs);
			oLogger.debug("process() : Login Data: RS: "
					+ oLoginData.getRelayState() + ", PIH: "
					+ oLoginData.getProviderIDHash());
			oLogger.debug("process() : Received :  RS=" + sRelayState
					+ ", PIH=" + oReceivedSAMLData.getProviderIDHash());
			return oMapping.findForward(ILinkConstants.FWD_SUCCESS);
		}

		String sArtifactConsumerService = ResolverClient.getMetaDataIDP(
				oLoginData.getIDPMetaDataEP())
				.getArtifactResolutionServiceURL();

		String sArtifactResolveXML = ISSOClient
				.createSAMLArtifactResolveRequest(oReceivedSAMLData
						.getArtifact());

		Envelope oEnvelope = ISSOClient.createSOAPEnvelope(sArtifactResolveXML);

		// TODO TO BE REMOVED
		MessageResources resources = getResources(oRequest);
		String cert_path = resources.getMessage("cert.path");
		String keystore_pwd = resources.getMessage("cert.pwd");
		boolean isSecure = Boolean.parseBoolean(resources.getMessage("secure"));
		Envelope oReceivedEnvelope = null;
		if (isSecure) {
			oReceivedEnvelope = ISSOClient.sendAndReceiveSOAPEnvelope(
					oEnvelope, sArtifactConsumerService);
		} else {
			oReceivedEnvelope = ISSOClient.sendAndReceiveSOAPEnvelope(
					oEnvelope, sArtifactConsumerService, cert_path,
					keystore_pwd);
		}
		oLogger.debug("process() : Soap envelope received: "
				+ oReceivedEnvelope);
		String sArtifactResponseXML = ISSOClient
				.getArtifactResponseFromSOAPEnvelpe(oReceivedEnvelope);

		SAMLDataObject oSAMLAuthResponseData = ISSOClient
				.getAuthnResponseValuesFromArtifactResponse(sArtifactResponseXML);

		if (!oLoginData.getGlobalInumber().equals(
				oSAMLAuthResponseData.getSubjectNameIDNameQualifier())
				|| !oSAMLAuthResponseData.getSAMLStatus().equals(
						ISSOClient.SAML_STATUS_SUCCESS)) {
			oMsgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
					ILinkConstants.ERR_INVALID_AUTHENTICATION, "request"));
			saveErrors(oRequest.getSession(false), oMsgs);
			oLogger.debug("process() : Expected GIN:"
					+ oLoginData.getGlobalInumber() + ", received:"
					+ oSAMLAuthResponseData.getSubjectNameIDNameQualifier());
			oLogger.debug("process() : Received STATUS:"
					+ oSAMLAuthResponseData.getSAMLStatus());
			oLogger.info("process() : exit");
			return oMapping.findForward(ILinkConstants.FWD_SUCCESS);
		}
		oLoginData.setLoginStatus(true);
		oLoginData.setSAMLData(oSAMLAuthResponseData);
		oMsgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
				ILinkConstants.MSG_LOGIN_SUCCESS));
		saveErrors(oRequest.getSession(false), oMsgs);
		oLogger.info("process() : successful login");
		return oMapping.findForward(ILinkConstants.FWD_SUCCESS);

	}

}
